package com.hejia.alauda.service;

import com.hejia.alauda.entity.*;
import com.hejia.alauda.entity.Product.Category;
import com.hejia.alauda.entity.example.ProductExample;
import com.hejia.alauda.entity.example.TemplateExample;
import com.hejia.alauda.entity.example.TemplateFieldExample;
import com.hejia.alauda.exception.BusinessException;
import com.hejia.alauda.jms.AlaudaSender;
import com.hejia.alauda.utils.Pager;

import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

/**
 * Created by Johnny(johnny@hejiajinrong.com) on 14-9-4.
 */
public interface ProductService {

	// 预售产品
	Pager<Product> getPresellProducts(Pager<Product> pager, String channel);

	// 在售产品
	Pager<Product> getOnsellProducts(Pager<Product> pager, String channel);

	// 售罄产品
	Pager<Product> getSoldoutProducts(String createDate, Pager<Product> pager, String channel);
	
	public Pager<Product> getSoldoutProducts(String createDate,Pager<Product> pager, String channel, String orderBy);

	// 所有产品
	Pager<Product> getAllProducts(Pager<Product> pager);
	
	// 所有回款产品
	Pager<Product> getRepaidProducts(Pager<Product> pager);

	// 所有产品
	Pager<Product> getAllProducts(ProductExample exp, Pager<Product> pager);

	Product getProductById(Long productId);

	Product getProductBySerial(String serial);

	@Transactional(readOnly = false, rollbackFor = Exception.class)
	boolean saveProduct(Product product) throws BusinessException;
	
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	boolean deleteProduct(String serial) throws Exception;

	@Transactional(readOnly = false, rollbackFor = Exception.class)
	boolean updateProduct(Product product, String serial) throws BusinessException;

	/**
	 * 判断 typeId 是否已被产品使用
	 *
	 * @param typeId
	 * @return true false
	 */
	boolean isTypeIdInUse(Long typeId);

	/**
	 * 上架产品
	 * 
	 * @param serial
	 *            产品编号
	 * @return
	 */
	boolean publishProduct(String serial);

	/**
	 * 计算金融包的每天的利息
	 * 
	 * @param financing_id
	 * @return
	 */
	BigDecimal calculateDayInterest(Long financing_id);

	/**
	 * 查询或有产品列表（带分页）
	 * 
	 * @param pager
	 * @return
	 */
	Pager<Product> findProductsByPage(Map<String, Object> params,
			Pager<Product> pager);

	/**
	 * 判断产品是否到期后全部兑付
	 * 
	 * @param product
	 * @return
	 */
	public boolean isProductPayback(Product product);

	/**
	 * 更新产品兑付时间
	 * 
	 * @param id
	 */
	public void updateCashTime(Long id);

	/**
	 * 查找产品
	 * 
	 * @param id
	 *            金融资产ID
	 * @return
	 */
	List<Product> findProductsByFinancialAssetId(Long id);

	/**
	 * 根据产品查询购买人数
	 * 
	 * @return
	 */
	Integer findNumberOfShoppersByProduct(Product product);

	public void addProductOutStock(Product product);

	/**
	 * 查询最新的月享和季享产品
	 * 
	 * @return
	 */
	public Product findLastProdutc(String param);


    /**
     * 分页列出产品类型
     *
     * @param pager
     *            分页信息
     * @return 模板分页
     */
    Pager<ProductType> listProductType(Pager<ProductType> pager);

    /**
     * 更新产品类别
     *
     * @param type
     * @return
     */
    boolean updateProductType(ProductType type);

    /**
     * 获取产品类别
     *
     * @param id
     * @return
     */
    ProductType getProductTypeById(Long id);

    /**
     * 批量插入拓展字段表
     *
     * @param list
     *            字段表列表
     */
    void insertField(List<ProductTypeField> list);

    /**
     * 根据产品类型ID获取拓展字段集合
     *
     * @param typeID
     *            产品类型ID
     * @return
     */
    List<ProductTypeField> findFieldsByTypeId(Long typeID);

    /**
     * 根据 产品类别 id 删除字段
     *
     * @param typeId
     * @return
     */
    boolean deleteField(Long typeId);

    /**
     * 插入产品类型字段值
     *
     * @param productTypeValue 字段值
     * @return 返回true false
     */
    boolean insertProductTypeValue(ProductTypeValue productTypeValue);

    /**
     * 更新产品类型字段值
     *
     * @param productTypeValue 字段值
     * @return 返回true false
     */
    boolean updateProductTypeValue(ProductTypeValue productTypeValue);

    /**
     * 根据产品id查询自定义字段值
     *
     * @param productId
     *            产品id
     * @return 返回产品字段值实体
     */
    ProductTypeValue findProductTypeValueByProductId(Long productId);

    /**
     * 删除产品分类值
     *
     * @param productTypeValue
     * @return
     */
    boolean deleteProductTypeValue(ProductTypeValue productTypeValue);



    /**
     * 分页列出模板
     *
     * @param pager 分页信息
     * @return 模板分页
     */
    Pager<Template> listTemplates(Pager<Template> pager);

    /**
     * 根据条件查询模板 带分页
     *
     * @param example 条件
     * @param pager 分页信息
     * @return 模板分页
     */
    Pager<Template> getAllTemplateByCondition(TemplateExample example, Pager<Template> pager);

    /**
     * 插入一个模板
     *
     * @param template 模板
     * @return 返回是否成功
     */
    boolean addTemplate(Template template);

    /**
     * 查找最新的模板记录
     *
     * @return 返回一个模板
     */
    Template findLastedTemplate();

    /**
     * 查询所有模板
     *
     * @return 返回list
     */
    List<Template> getAllTemplates();

    /**
     * 根据id删除模板
     *
     * @param id
     * @return
     */
    boolean deleteTemplateById(Long id);

    /**
     * 根据id查找模板
     *
     * @param id 模板id
     * @return
     */
    Template getTemplateById(Long id);

    /**
     * 修改模板
     *
     * @param template
     * @return
     */
    boolean updateTemplate(Template template);

    /**
     * 插入一条记录
     *
     * @param templateValue templateValue
     * @return 返回插入是否成功
     */
    boolean insertEntity(TemplateValue templateValue);

    /**
     * 更新模版属性值
     *
     * @param templateValue
     * @return
     */
    boolean updateTemplateValue(TemplateValue templateValue);

    /**
     * 根据关联id删除记录，关联id是产品id
     *
     * @param relationId
     * @return
     */
    boolean deleteByRelationId(String relationId);

    /**
     * 根据关联id(产品id)查找对应字段值
     *
     * @param relationId 产品id
     * @return 模板字段值
     */
    TemplateValue findTemplateValueByRelationId(Long relationId);

    /**
     * 根据关联id(产品id)、模版ID查找对应字段值
     * @param relationId	产品id
     * @param templateId	模版ID
     * @return
     */

    TemplateValue findTemplateValueByRelationIdAndTemplateId(Long relationId,Long templateId);


    /**
     * 批量插入拓展字段表
     *
     * @param list 字段表列表
     */
    void insertBatch(List<TemplateField> list);

    /**
     * 根据模板id查找模板的拓展字段
     *
     * @param id 模板id
     * @return
     */
    List<TemplateField> findTemplateFieldsByTemplateId(Long id);

    /**
     * 根据条件查询拓展字段 带分页
     *
     * @param example 条件
     * @param pager 分页信息
     * @return 分页的拓展字段表
     */
    Pager<TemplateField> getAllTemplateFieldsByCondition(TemplateFieldExample example, Pager<TemplateField> pager);

    /**
     * 根据templateid删除拓展字段
     *
     * @param id
     * @return
     */
    boolean deleteByTemplateId(Long id);

    /**
     * 增加协议
     *
     * @param protocol
     * @return
     */
    boolean addProtocol(Protocol protocol);

    /**
     * 查找协议
     *
     * @param id
     * @return
     */
    Protocol findProtocolById(Long id);

    /**
     * 修改协议
     *
     * @param protocol
     * @return
     */
    boolean modifyProtocol(Protocol protocol);

    /**
     * 删除协议
     *
     * @param protocol
     * @return
     */
    boolean deleteProtocol(Protocol protocol);

    /**
     * 根据产品ID获取协议列表
     *
     * @param productId
     * @return
     */
    public List<Protocol> getProtocolsByProductId(Long productId);

    /**
     * 监视产品的交易状态
     */
    void monitorProduct(Executor executor,AlaudaSender sender);

    /**
     * 设置资产协议号产品部分
     * @param productId 产品ID
     */
	void setProductAgreementNumber(Long productId);

	/**
     * 设置资产协议号资产部分
     * @param financingId 资产ID
     */
	void setFinancingAgreementNumber(Long financingId);
	
	/**
	 * 根据产品种类查询产品列表
	 * @param category
	 * @return
	 */
	List<Product> findProductsByCategory(Product.Category category);

	/**
	 * 到点上架产品
	 * @param serial 产品编号
	 * @return	
	 */
	boolean timePublishProduct(String serial);

	/**
	 * 到点上架产品，提前30分钟上架
	 */
	void timePublishProducts();

	/**
	 * 查询最新的新手产品
	 * @return	最新的新手产品
	 */
	Product findLastRookieProdutc();
	
	/**
	 * 根据节假日调整产品发售期限
	 * @param product 产品
	 * @param term	产品期限
	 * @param maxTerm 最大产品期限
	 */
	public void adjustProductTermByHoliday(Product product, Integer term, Integer maxTerm);

	/**
	 * 检查金融资产库存，包含排期预售部分
	 * @param product	产品
	 */
	void checkInventory(Product product);
	
	/**
	 * 根据条件查询产品列表
	 * @param example
	 * @return
	 */
	Pager<Product> findProductListByExample(ProductExample example, Pager<Product> pager, boolean isPagination);

	/**
	 * 计算指定类别和大于指定可售金额的在售产品数量
	 * @param category 	产品类别
	 * @param rookie 是否新手标
	 * @param availableSellAmount	可售金额
	 * @return	在售产品数量
	 */
	Integer sumOnSellProductByCategoryAndAmount(Category category, boolean rookie, Integer availableSellAmount);

	/**
	 * 查询最新的产品
	 * @param category 产品类别
	 * @param rookie 是否新手标
	 * @return 最新的产品
	 */
	Product findLastProdutc(Category category, boolean rookie);

	/**
	 * 查询最大产品编号
	 * @param category
	 * @return
	 */
	Integer findMaxProductNumber(Category category);
	
	
	void sendNotifyForSoldout(String serial);
	
	/**
	 * 给订阅过产品预售短信的用户发送预售短信
	 * @param content
	 */
	void sendSaleNotify(String content);
	
	void sendSaleNotify(Date date);
	
	Integer countSaleNotify();
	
	/**
	 * 根据产品获得投资记录
	 * @param productId
	 * @return
	 */
	List<Map<String, Object>> findFinancialListByProduct(Long productId);
	
	String renderingContent(com.hejia.alauda.entity.Template template,
			Product product);
	 
	
	/**********
	 * 新版
	 *
	 */
	Product getRecommendProductForHomePage(String channel);
	
	Product getOnSaleRookieProduct();

	Pager<Financing> findProductTradeRecord(Product product, Pager<Financing> pager);
	
	List<SaleActivity> findProductSaleAcitvity(String aids);
	
	SaleActivity getInvitationSaleActivity();
	
	Boolean sendSaleNotify(Product product);
}
